#include "TestTexture2D.h"
#include "ErrorDetect.h"
#include "imgui/imgui.h"
#include "VertexArray.h"
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
#include "IndexBuffer.h"
#include "Renderer.h"
#include "Shader.h"
#include "Texture.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

namespace test
{
	TestTexture2D::TestTexture2D()
		:m_TranslationA(200, 200, 0), m_TranslationB(400, 200, 0),
		m_Proj(glm::ortho(0.0f, 960.0f, 0.0f, 540.0f, -1.0f, 1.0f)),
		m_View(glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0)))
	{
		float positions[] = {
			// 调整贴图的位置,使中心点正好使原点，四个角的坐标如下:
			-50.0f, -50.0f, 0.0f, 0.0f,   // 1
			 50.0f, -50.0f, 1.0f, 0.0f,   // 2
			 50.0f,  50.0f, 1.0f, 1.0f,   // 3
			-50.0f,  50.0f, 0.0f, 1.0f,   // 4
		};
		unsigned int indices[]
		{
			0,1,2,
			2,3,0,
		};

		GLCall(glEnable(GL_BLEND));
		GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
		
		m_Shader = std::make_unique<Shader>("res/shaders/Basic.shader");
		m_VAO = std::make_unique<VertexArray>();
		m_VertexBuffer = std::make_unique<VertexBuffer>(positions, 4 * 4 * sizeof(float));
		VertexBufferLayout layout;
		layout.Push<float>(2, GL_FALSE);
		layout.Push<float>(2, GL_FALSE);
		m_VAO->AddBuffer(*m_VertexBuffer, layout);
		m_IndexBuffer = std::make_unique<IndexBuffer>(indices, 6);
		
		m_Shader->Bind();

		m_Texture = std::make_unique<Texture>("res/textures/icon.png");
		int slot = 0;
		// 告诉shader我们根据那个texture的slot来取样（sample form）
		// 在CPU端用 glActiveTexture 控制是哪个slot，然后再讲slot值传到shader里
		// 在shader端用 uniform sampler2D 类型的变量接受这个 slot值 即可访问到相应的texture数据!
		// (sampler slot！)
		m_Texture->Bind(slot);
		m_Shader->SetUniform1i("u_Texture", slot);
		
	}

	TestTexture2D::~TestTexture2D()
	{
	}

	void TestTexture2D::OnUpdate(float deltaTime)
	{
	}

	void TestTexture2D::OnRender()
	{
		GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
		GLCall(glClear(GL_COLOR_BUFFER_BIT));
		Renderer renderer;
		m_Texture->Bind();
		{
			glm::mat4 model = glm::translate(glm::mat4(1.0f), m_TranslationA);
			glm::mat4 mvp = m_Proj * m_View * model;
			m_Shader->Bind();
			m_Shader->SetUniformMat4f("u_MVP", mvp);
			renderer.Draw(*m_VAO, *m_IndexBuffer, *m_Shader);
		}
		{
			glm::mat4 model = glm::translate(glm::mat4(1.0f), m_TranslationB);
			glm::mat4 mvp = m_Proj * m_View * model;
			m_Shader->Bind();
			m_Shader->SetUniformMat4f("u_MVP", mvp);
			renderer.Draw(*m_VAO, *m_IndexBuffer, *m_Shader);
		}
		
	}

	void TestTexture2D::OnImGuiRender()
	{
		ImGui::SliderFloat3("TranslateA", &m_TranslationA.x, 0.0f, 960.0f);
		ImGui::SliderFloat3("TranslateB", &m_TranslationB.x, 0.0f, 960.0f);
		ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
			1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		
	}
}
